// 拖拽功能的自定义 Hook

import { useState, useCallback, useRef } from 'react';
import { FileItem } from '../types/filesystem';

interface DragState {
  isDragging: boolean;
  draggedFiles: FileItem[];
  dragOverTarget: string | null;
  dragStartPosition: { x: number; y: number } | null;
}

interface UseDragAndDropOptions {
  onFileDrop: (draggedFiles: FileItem[], targetPath: string) => Promise<boolean>;
  onFileMove: (sourcePath: string, targetPath: string) => Promise<boolean>;
}

export const useDragAndDrop = (options: UseDragAndDropOptions) => {
  const { onFileDrop, onFileMove } = options;
  
  const [dragState, setDragState] = useState<DragState>({
    isDragging: false,
    draggedFiles: [],
    dragOverTarget: null,
    dragStartPosition: null,
  });

  const dragTimeoutRef = useRef<NodeJS.Timeout | null>(null);

  // 开始拖拽
  const handleDragStart = useCallback((
    e: React.DragEvent,
    files: FileItem[],
    startPosition: { x: number; y: number }
  ) => {
    e.dataTransfer.effectAllowed = 'move';
    e.dataTransfer.setData('text/plain', JSON.stringify(files.map(f => f.path)));
    
    setDragState({
      isDragging: true,
      draggedFiles: files,
      dragOverTarget: null,
      dragStartPosition: startPosition,
    });

    // 设置拖拽图像
    if (files.length === 1) {
      e.dataTransfer.setData('text/html', `<div>${files[0].name}</div>`);
    } else {
      e.dataTransfer.setData('text/html', `<div>${files.length} 个文件</div>`);
    }
  }, []);

  // 拖拽结束
  const handleDragEnd = useCallback((e: React.DragEvent) => {
    setDragState({
      isDragging: false,
      draggedFiles: [],
      dragOverTarget: null,
      dragStartPosition: null,
    });

    if (dragTimeoutRef.current) {
      clearTimeout(dragTimeoutRef.current);
      dragTimeoutRef.current = null;
    }
  }, []);

  // 拖拽进入目标
  const handleDragEnter = useCallback((e: React.DragEvent, targetFile: FileItem) => {
    e.preventDefault();
    
    // 只有目录可以作为拖拽目标
    if (targetFile.is_directory) {
      setDragState(prev => ({
        ...prev,
        dragOverTarget: targetFile.path,
      }));
    }
  }, []);

  // 拖拽在目标上方
  const handleDragOver = useCallback((e: React.DragEvent, targetFile: FileItem) => {
    e.preventDefault();
    
    if (targetFile.is_directory) {
      e.dataTransfer.dropEffect = 'move';
    } else {
      e.dataTransfer.dropEffect = 'none';
    }
  }, []);

  // 拖拽离开目标
  const handleDragLeave = useCallback((e: React.DragEvent, targetFile: FileItem) => {
    // 使用延时来避免在子元素间移动时触发 dragLeave
    if (dragTimeoutRef.current) {
      clearTimeout(dragTimeoutRef.current);
    }
    
    dragTimeoutRef.current = setTimeout(() => {
      setDragState(prev => ({
        ...prev,
        dragOverTarget: prev.dragOverTarget === targetFile.path ? null : prev.dragOverTarget,
      }));
    }, 50);
  }, []);

  // 放置文件
  const handleDrop = useCallback(async (e: React.DragEvent, targetFile: FileItem) => {
    e.preventDefault();
    
    if (!targetFile.is_directory) {
      return;
    }

    const { draggedFiles } = dragState;
    
    if (draggedFiles.length === 0) {
      return;
    }

    // 检查是否拖拽到自己或子目录
    const isInvalidDrop = draggedFiles.some(file => {
      if (file.path === targetFile.path) {
        return true; // 不能拖拽到自己
      }
      if (targetFile.path.startsWith(file.path + '/')) {
        return true; // 不能拖拽到自己的子目录
      }
      return false;
    });

    if (isInvalidDrop) {
      console.warn('Invalid drop target');
      return;
    }

    try {
      // 执行文件移动
      const results = await Promise.all(
        draggedFiles.map(file => {
          const fileName = file.name;
          const newPath = `${targetFile.path}/${fileName}`;
          return onFileMove(file.path, newPath);
        })
      );

      // 检查是否所有操作都成功
      const allSuccess = results.every(result => result);
      
      if (allSuccess) {
        console.log('Files moved successfully');
      } else {
        console.error('Some files failed to move');
      }
    } catch (error) {
      console.error('Failed to move files:', error);
    } finally {
      setDragState({
        isDragging: false,
        draggedFiles: [],
        dragOverTarget: null,
        dragStartPosition: null,
      });
    }
  }, [dragState, onFileMove]);

  // 检查是否可以拖拽
  const canDrag = useCallback((file: FileItem) => {
    // 可以根据需要添加更多限制
    return true;
  }, []);

  // 检查是否可以作为拖拽目标
  const canDrop = useCallback((targetFile: FileItem, draggedFiles: FileItem[]) => {
    if (!targetFile.is_directory) {
      return false;
    }

    // 检查是否拖拽到自己或父目录
    return !draggedFiles.some(file => {
      if (file.path === targetFile.path) {
        return true;
      }
      if (targetFile.path.startsWith(file.path + '/')) {
        return true;
      }
      return false;
    });
  }, []);

  // 获取拖拽样式
  const getDragStyles = useCallback((file: FileItem) => {
    const isDraggedFile = dragState.draggedFiles.some(f => f.path === file.path);
    const isDragTarget = dragState.dragOverTarget === file.path;
    
    let styles = '';
    
    if (isDraggedFile && dragState.isDragging) {
      styles += ' opacity-50';
    }
    
    if (isDragTarget && dragState.isDragging) {
      styles += ' bg-blue-100 dark:bg-blue-900/30 border-blue-300 dark:border-blue-600';
    }
    
    return styles;
  }, [dragState]);

  // 获取拖拽指示器
  const getDragIndicator = useCallback((file: FileItem) => {
    const isDragTarget = dragState.dragOverTarget === file.path;
    
    if (isDragTarget && dragState.isDragging && file.is_directory) {
      return (
        <div className="absolute inset-0 border-2 border-dashed border-blue-400 bg-blue-50 dark:bg-blue-900/20 rounded pointer-events-none" />
      );
    }
    
    return null;
  }, [dragState]);

  return {
    dragState,
    handleDragStart,
    handleDragEnd,
    handleDragEnter,
    handleDragOver,
    handleDragLeave,
    handleDrop,
    canDrag,
    canDrop,
    getDragStyles,
    getDragIndicator,
  };
};

// 批量选择的自定义 Hook
interface UseMultiSelectOptions {
  onSelectionChange: (selectedPaths: string[]) => void;
}

export const useMultiSelect = (options: UseMultiSelectOptions) => {
  const { onSelectionChange } = options;
  const [selectedPaths, setSelectedPaths] = useState<string[]>([]);
  const [lastSelectedPath, setLastSelectedPath] = useState<string | null>(null);

  // 选择单个文件
  const selectFile = useCallback((
    filePath: string,
    isCtrlClick: boolean = false,
    isShiftClick: boolean = false,
    allFiles: FileItem[] = []
  ) => {
    setSelectedPaths(prev => {
      let newSelection: string[];

      if (isShiftClick && lastSelectedPath) {
        // Shift+点击：选择范围
        const lastIndex = allFiles.findIndex(f => f.path === lastSelectedPath);
        const currentIndex = allFiles.findIndex(f => f.path === filePath);
        
        if (lastIndex !== -1 && currentIndex !== -1) {
          const startIndex = Math.min(lastIndex, currentIndex);
          const endIndex = Math.max(lastIndex, currentIndex);
          const rangeFiles = allFiles.slice(startIndex, endIndex + 1);
          
          newSelection = [...new Set([...prev, ...rangeFiles.map(f => f.path)])];
        } else {
          newSelection = [...prev, filePath];
        }
      } else if (isCtrlClick) {
        // Ctrl+点击：切换选择
        if (prev.includes(filePath)) {
          newSelection = prev.filter(path => path !== filePath);
        } else {
          newSelection = [...prev, filePath];
        }
      } else {
        // 普通点击：单选
        newSelection = [filePath];
      }

      onSelectionChange(newSelection);
      return newSelection;
    });

    setLastSelectedPath(filePath);
  }, [lastSelectedPath, onSelectionChange]);

  // 清除选择
  const clearSelection = useCallback(() => {
    setSelectedPaths([]);
    setLastSelectedPath(null);
    onSelectionChange([]);
  }, [onSelectionChange]);

  // 全选
  const selectAll = useCallback((allFiles: FileItem[]) => {
    const allPaths = allFiles.map(f => f.path);
    setSelectedPaths(allPaths);
    onSelectionChange(allPaths);
  }, [onSelectionChange]);

  // 反选
  const invertSelection = useCallback((allFiles: FileItem[]) => {
    const allPaths = allFiles.map(f => f.path);
    const newSelection = allPaths.filter(path => !selectedPaths.includes(path));
    setSelectedPaths(newSelection);
    onSelectionChange(newSelection);
  }, [selectedPaths, onSelectionChange]);

  // 检查文件是否被选中
  const isSelected = useCallback((filePath: string) => {
    return selectedPaths.includes(filePath);
  }, [selectedPaths]);

  return {
    selectedPaths,
    selectFile,
    clearSelection,
    selectAll,
    invertSelection,
    isSelected,
  };
};
